import './style.scss'
import React, { useState, useRef } from 'react'
import type { FC } from 'react'
import {
  Col,
  Form,
  Row,
  Input,
  Space,
  Button,
  Upload,
  message,
  Flex
} from 'antd'
import {
  MinusCircleOutlined,
  PlusOutlined,
  InboxOutlined
} from '@ant-design/icons'
import type { FormProps, UploadProps } from 'antd'
import SparkMD5 from 'spark-md5'
import { delay, readerFile } from '@/utils/tools'
import { uploadChunkVideoApi, mergeChunkVideoApi } from '@/services/filmApi'
import MyEditor from '@/components/MyEditor'
import type { IEditorRef } from '@/components/MyEditor'

const FilmAdd: FC = () => {
  const [playUrl, setPlayUrl] = useState('')
  const [video, setVideo] = useState('')
  const [form] = Form.useForm()
  const editorRef = useRef<IEditorRef>(null!)

  const onFinish: FormProps['onFinish'] = (values) => {
    values = {
      ...values,
      actors: values.actors.map((item: any) => item.actor),
      video,
      intro: editorRef.current.getHtml()
    }
    console.log(values)
    form.resetFields()
    setPlayUrl('')
    setVideo('')
    editorRef.current.setHtml('')
  }

  // 文件上传
  const onBeforeUpload: UploadProps['beforeUpload'] = async (file) => {
    // 判断只能上传.mp4 .avi .mkv .rmvb .wmv .flv
    const isAllowType = /\.(mp4|avi|mkv|rmvb|wmv|flv)$/.test(file.name)
    if (!isAllowType) {
      message.error('只能上传.mp4 .avi .mkv .rmvb .wmv .flv', 3)
      return false
    }
    // 获取上传视频的扩展名
    const extName = file.name.split('.').pop()!

    // 高性能的根据文件内容生成md5库
    const spark = new SparkMD5()
    let fileContentBuffer: any = await readerFile(file)
    spark.append(fileContentBuffer)
    // 上传的文件内容生成的hash值
    const hashName = spark.end()

    // 固定切片数量去进行切片上传
    const partNum = 3
    // 每个切片它的大小
    const partSize = file.size / partNum
    // 存储切片的容器
    const chunks = []
    for (let i = 0; i < partNum; i++) {
      let start = i * partSize
      let end = (i + 1) * partSize
      chunks.push({
        index: i.toString(),
        name: hashName,
        data: file.slice(start, end)
      })
    }

    // 准备请求
    let requestFiles: Array<any> = []
    chunks.forEach((item) => {
      let cb = () => {
        const formData = new FormData()
        formData.append('index', item.index)
        formData.append('name', item.name)
        formData.append('file', item.data)
        return uploadChunkVideoApi(formData)
      }
      requestFiles.push(cb)
    })

    let requestIndex = 0
    const complete = async () => {
      // 在通知文件合并时要告诉服务器它合并后的文件的类型 xxx.mp4
      let ret = await mergeChunkVideoApi(hashName, extName)
      // 回显
      setPlayUrl(ret.data.url)
      // 上传到服务器
      setVideo(ret.data.path)
    }
    const next = async () => {
      if (requestIndex >= requestFiles.length) {
        await delay(600)
        await complete()
        return
      }
      try {
        await requestFiles[requestIndex++]()
        next()
      } catch (error) {}
    }

    next()

    return false
  }

  return (
    <div className="film-add-box">
      <Form
        form={form}
        autoComplete="off"
        labelCol={{ span: 4 }}
        wrapperCol={{ span: 16 }}
        onFinish={onFinish}
      >
        <Row gutter={20}>
          <Col span={12}>
            <Form.Item label="电影名称" name="name">
              <Input />
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label="电影导演" name="director">
              <Input />
            </Form.Item>
          </Col>
        </Row>
        <Row gutter={20}>
          <Col span={20}>
            {/* label="主要演员" */}
            <Form.List name="actors" initialValue={[{ key: Date.now() }]}>
              {(fields, { add, remove }) => {
                return (
                  <>
                    {fields.map(({ key, name }) => (
                      <Space
                        key={key}
                        style={{ display: 'flex', marginBottom: 8 }}
                        align="baseline"
                      >
                        <Form.Item
                          label={'演员 - ' + name}
                          name={[name, 'actor']}
                          labelCol={{ span: 10 }}
                          wrapperCol={{ span: 14 }}
                          rules={[
                            {
                              required: true,
                              whitespace: true,
                              message: '演员姓名必须要填写'
                            }
                          ]}
                        >
                          <Input placeholder="填写演员姓名" />
                        </Form.Item>
                        {name == 0 ? (
                          <Button
                            style={{ width: 80 }}
                            type="dashed"
                            onClick={() => add()}
                            block
                            icon={<PlusOutlined />}
                          >
                            添加
                          </Button>
                        ) : (
                          <Button
                            style={{ width: 80 }}
                            type="dashed"
                            onClick={() => remove(name)}
                            block
                            icon={<MinusCircleOutlined />}
                          >
                            删除
                          </Button>
                        )}
                      </Space>
                    ))}
                  </>
                )
              }}
            </Form.List>
          </Col>
        </Row>
        <Row gutter={20}>
          <Col span={12}>
            <Form.Item label="电影预告" name="video">
              <Upload.Dragger
                name="files"
                fileList={[]}
                action=""
                beforeUpload={onBeforeUpload}
              >
                <p className="ant-upload-drag-icon">
                  <InboxOutlined />
                </p>
                <p className="ant-upload-text">点击或拖拽都可以上传电影预告</p>
                <p className="ant-upload-hint">
                  支持扩展名：.mp4 .avi .mkv .rmvb .wmv .flv
                </p>
              </Upload.Dragger>
            </Form.Item>
          </Col>
          <Col span={12}>
            <div>
              {playUrl ? (
                <video
                  src={playUrl}
                  controls
                  style={{ width: 300, height: 220 }}
                />
              ) : (
                <div
                  style={{ width: 300, height: 220, background: '#ccc' }}
                ></div>
              )}
            </div>
          </Col>
        </Row>
        <Row gutter={20}>
          <Col span={24}>
            <Form.Item label="电影介绍" name="intro">
              <MyEditor ref={editorRef} color="#f23e3e" />
            </Form.Item>
          </Col>
        </Row>
        <Row gutter={20}>
          <Col span={24}>
            <Form.Item wrapperCol={{ offset: 4, span: 16 }}>
              <Flex gap="small">
                <Button type="primary" htmlType="submit">
                  保存用户信息
                </Button>
                <Button
                  type="default"
                  onClick={() => {
                    form.resetFields()
                    setPlayUrl('')
                    setVideo('')
                    editorRef.current.setHtml('')
                  }}
                >
                  重置表单
                </Button>
              </Flex>
            </Form.Item>
          </Col>
        </Row>
      </Form>
    </div>
  )
}

export default FilmAdd
